package com.bungarus.busi;

import com.bungarus.model.Member;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.*;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by tang on 2019/2/7.
 */
@Component
public class GroupServiceLogin implements Login{

    private String endPoint;
    private int timeout;

    private CloseableHttpClient httpClient;

    @Autowired
    public GroupServiceLogin(@Qualifier("gsEndPoint")String endPoint,
                             @Qualifier("gsTimeout")String timeoutStr) {
        this.endPoint = endPoint;
        this.timeout = Integer.parseInt(timeoutStr);
        init();
    }

    private void init() {
        PoolingHttpClientConnectionManager clientConnectionManager = new PoolingHttpClientConnectionManager();
        clientConnectionManager.setMaxTotal(Integer.MAX_VALUE);
        clientConnectionManager.setDefaultMaxPerRoute(Integer.MAX_VALUE);

        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(timeout)
                .setConnectTimeout(timeout * 3)
                .setSocketTimeout(timeout * 3)
                .build();

        CloseableHttpClient client = HttpClients.custom()
                .setKeepAliveStrategy((HttpResponse response, HttpContext context) -> {
                    HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
                    while (it.hasNext()) {
                        HeaderElement he = it.nextElement();
                        String param = he.getName();
                        String value = he.getValue();
                        if (value != null && param.equalsIgnoreCase
                                ("timeout")) {
                            return Long.parseLong(value) * 1000;
                        }
                    }
                    return 6 * 1000;
                })
                .setConnectionManager(clientConnectionManager)
                .setDefaultRequestConfig(requestConfig)
                .build();

        this.httpClient = client;
    }

    @PreDestroy
    private void destroy() {
        try {
            this.httpClient.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Member login(String username, String pwd, String tenantId) {
        //endPoint: http://groupservice.bungarus.com:9060
        if(null == this.endPoint || this.endPoint.length() <= 0){
            throw new IllegalStateException("Endpoint of service for authenticating user needed.");
        }
        StringBuilder sb = new StringBuilder(this.endPoint);
        if(!this.endPoint.endsWith("/")) {
            sb.append("/");
        }
        sb.append("login/");
        sb.append(tenantId);

        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("account", username));
        params.add(new BasicNameValuePair("pwd", pwd));

        HttpPost postMethod = new HttpPost(sb.toString());
        HttpEntity reqEntity = new UrlEncodedFormEntity(params, Charset.forName("utf-8"));
        postMethod.setEntity(reqEntity);
        try {
            CloseableHttpResponse response = httpClient.execute(postMethod);
            if(HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {
                HttpEntity entity = response.getEntity();
                if (entity.getContentType().getValue().contains("application/json")) {
                    String strEntity = EntityUtils.toString(entity, "utf-8");

                    ObjectMapper objectMapper = new ObjectMapper();
                    return objectMapper.readValue(strEntity, Member.class);
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Member auth(String token, String username, String tenantId) {
        return null;
    }
}
